package Study1;
/*类的进一步认识*/

class Demo01 {
    public String name;
}



class Demo02 {
    private String name;
    private int age;

    public Demo02(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}



class Demo03 {
    private String name;
    Demo03() {   // 构造器方法，或者是函数
        System.out.println("无参数构造器");
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


class Demo04 {
    private String name;
    private int age;
    Demo04(String name,int age) {  // 有参数的构造器方法(函数)
        this.name = name;
        this.age = age;
        System.out.println("有参数的构造器方法(函数)");
    }
}


class Demo05 {
    private String name;
    private int age;
    public Demo05() {
        System.out.println("无参数的构造方法，Demo05<int> !");
    }

}


class Demo06 {
    private String name;
    private int age;
    public Demo06(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Demo06<String int >,有参数的构造方法");
    }
}


class Demo07 {
    private String name;
    private int age;
    public Demo07() {
        System.out.println("无参数构造方法");
    }
    public Demo07(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参数构造方法");
    }
}


class Demo08 {
    private String name;
    private int age;
    public Demo08() {
        this("你好世界",18);
        System.out.println("无参数构造方法");
    }
    public Demo08(String name , int age ) {
        this.name = name;
        this.age = age;
        System.out.println("有参数构造方法");
    }
    public void test() {
//        this("Test",18); // this()调用自己的构造方法，只能是在构造方法中使用才行，不然报错的
        System.out.println("测试");
    }
}



class Demo09 {
    private String name;
    private int age;
    public Demo09() {
        this("你好世界",18);
//        this("Hello World",19); 报错，this(),必须要在构造方法中的第一行，作为第一个条语句才行
        System.out.println("无参数构造方法");
//        this("你好世界",18);  报错，this()，必须要在构造方法中的第一行，作为第一个语句才行

    }

    public Demo09(String name , int age ) {
        this.name = name;
        this.age = age;
        System.out.println("有参数构造方法");
    }

}


class Demo10 {
    private String name = "你好世界";
    private int age = 18;


    public Demo10() {
        System.out.println("无参数构造方法");
    }

    public String getName() {
        return this.name;
    }
    public int getAge() {
        return this.age;
    }

    public void print() {
        System.out.println(this.getName());
        System.out.println(getName());
        System.out.println(this.age);
    }

}


class Demo12 {
    private String name;
    private int age ;
    public static int count;

    public Demo12() {
        System.out.println("Demo12 <int>,无参数构造方法");
    }

    {
//        实例代码块
        this.name = "你好世界";
        count = 99;
/*        System.out.println(this.name);
        System.out.println(count);*/
        System.out.println("实例代码块 又名: 构造代码块......");
    }

    static {
//        this.name = "Hello World"; // 报错，因为静态的不能直接访问非静态的，
        count = 99;  // 静态的在静态中不要加 this. 关键字引用对象
        System.out.println("静态代码块.......");
    }

}


class Demo11 {
    private String name ;
    private int age;
    public static int count;

    public Demo11() {
        System.out.println("无参数的构造方法");
    }

    static {  // 静态的无妨直接访问非静态的，因为创建的差;
        System.out.println("静态代码块");
    }

    {
        System.out.println("实例化代码块  又名：构造代码块");
    }

}


class Demo13 {
    private static int count = 0;
    static {
        count = 99;
        System.out.println("静态代码块......");
    }
    public static void func() {
        System.out.println("count:"+count);
    }
}


class Demo14 {
    static {
        count = 99;
        System.out.println("静态代码块");
    }

    private static int count = 100;

    public static void func() {
        System.out.println("count:"+count);
    }

}



class Demo15 {
    private String name = "小华";
    private int age = 18;
    public void eat() {
        System.out.println("吃饭");
    }
    public void print() {
        System.out.println(this.name);
        System.out.println(this.age);
    }

}
  public class Study16 {
    /* 匿名对象
    * 1.没有引用的对象称为匿名对象
    * 2.匿名对象只能在创建对象时使用(new): 就是实例化(new)的同时并使用引用
    * 3.如果一个对象只是用一次，后面不需要用了，可以考虑使用匿名对象*/
    public static void main(String[] args) {
        Demo15 demo15 = new Demo15();
        demo15.eat();
        demo15.eat();
        demo15.print();
        System.out.println("+++++++++++++++++++");
        new Demo15().eat();
        new Demo15().eat();
        new Demo15().print();
    }



    /* 代码块：{
    *   实例化代码块/构造代码块
    * }
    *
    * static{
    * 静态代码块
    * }
    *
    * 重点：
    * 代码块(实例代码块)(构造代码块)(静态代码块)只要创建了对象，实例化了，都会执行的
    * 静态的代码块最先执行,并且只会执行一次
    * 其次是实例代码块，实例化的多少次对象就会执行多少次;
    * 最后是构造代码块
    * 如果都是静态的成员变量，其数值的改变和定义的前后顺序有关的，以最后一次为主*/

      public static void main14(String[] args) {
          Demo14 demo14 = new Demo14();
          Demo14.func();
      }


      public static void main13(String[] args) {
          Demo13 demo13 = new Demo13();
          Demo13.func();
      }


    public static void main11(String[] args) {
        Demo11 demo11 = new Demo11();
        System.out.println("+++++++++++++++++++++++++");
        Demo11 demo112 = new Demo11();
    }
    public static void main12(String[] args) {
        Demo12 demo12 = new Demo12();
    }



    /*this 关键字的使用：
    * 1. this()，调用自己的构造方法，：注意只能在构造方法中使用
    * 2. this.data :调用当前的对象的属性(字段，成员变量，静态变量，都是一个意思的)
    * 3.this.fanc:  调用当前对象的方法;*/
    /* 面试题目： this 关键字代表对象，这句话是否对，不对为什么？
    * 不对，this 关键字代表的是引用对象，因为 当this()调用构造方法的时候，并没有出现报错的情况
    * 而new 实例化对象的时候必须满足：1.new 为对象开辟空间存放数据，
    * 2.调用完构造方法，只有调用完构造方法，对象才会加载到内存当中去
    * 如果this关键字表示的当前对象的话，我们在构造方法中使用this的时候应该是报错的因为
    * 这个时候构造方法并没有调用完，所以我们的对象也并没有创建出来，而我们的JVM 虚拟机是不允许我们调用
    * 一个还为创建出来的数据的，强制报错，而这里去明显没有，综上所述：this不是表示当前对象的
    * 而是引用当前对象的*/

//this.fanc(): 调用当前对象的方法；
    public static void main10(String[] args) {
        Demo10 demo10 = new Demo10();
        demo10.print();

    }

//    this(): 调用自己的构造方法，：注意只能在构造方法中使用；
//    并且要在构造方法中的第一行，作为第一条语句使用才行；
    public static void main9(String[] args) {
        Demo09 demo09 = new Demo09();
    }


    public static void main8(String[] args) {
        Demo08 demo08 = new Demo08(); // 调用无参数构造方法

    }



    public static void main7(String[] args) {
        Demo07 demo07 = new Demo07();
        System.out.println(demo07);  // 结果为经过哈希加密过后的地址;
        System.out.println("+++++++++++++++++++++++++++++");
        Demo07 demo072 = new Demo07("你好世界",18);
        System.out.println(demo072); // 结果是哈希加密过后的地址
    }



    public static void main6(String[] args) {
        Demo06 demo06 = new Demo06("小华",18); // 调用一个有参数的构造方法
//        Demo06 demo062 = new Demo06(); // 调用一个无参数的构造器，报错
        /*因为当你提供了一个有参数的构造方法，编译器就不会自动生成一个无参数的构造方法了，需要你自行建立才行*/
    }


    /*静态的数据只有一份且是存在于方法区中的，和类一起加载的内存当中的
    * 而非静态的数据成员是属于对象的，加载的堆区的
    * 构造方法它的方法名必须和类名完全一致才行
    * 提问：一个对象的产生，分为几步，他是如何产生的
    * 1. 为对象开辟空间 new
    * 2. 调用合适的构造方法（一定要有的）：构造方法的作用：构造对象的初始值
    * 3.合适意味者可以重载的：
    * 当没有提供构造方法的时候，那么编译器会自动生成一个无参数的构造方法*/
    public static void main5(String[] args) {
        Demo05 demo05 = new Demo05(); // 调用一个无参数的构造器
    }



    public static void main4(String[] args) {
        Demo04 demo04 = new Demo04("你好世界",18);
//        Demo04 demo040 = new Demo04(); // 报错
//        IDEA 快捷键 Alt+Insert + Constructor
/*当定义一个有参数的构造方法(函数),默认的无参构造器方法(函数),不会显示的，
* 所以这里报错，他找不到该空参数的构造器方法，所以你如果定义了一个有参数的构造器的同时又想，
* 调用一个没有参数的构造方法，就需要你自定义一个无参数的构造器才行*/

    }



    /*构造方法或者函数
    * 使用new 关键字创建对象的时候.需要有两个条件的满足
    * 1. new 为对象开辟空间
    * 2. 调用构造器，必须要调用完，构造器才可以创建出对象
    * 构造器作用：创建对象的
    * 定义构造器的条件：
    * 1.没有返回类型
    * 2.必须和类名完全一致
    * 3.构造器同方法一样可以重载：
    * 重载：
    * 1.前提：需要在同一个类中
    * 2.形参列表：类型不同
    * 3. 形参列表的中的个数不同
    * 一个类中什么都没有写，编译器会默认给予一个空形参的构造器*/
    public static void main3(String[] args) {
        Demo03 demo03 = new Demo03(); // 调用参数为空的，构造器方法，(函数)
        demo03.setName("Hello World");
        System.out.println(demo03.getName());
//        使用new 本质上是在调用构造器方法（函数）;

    }


    public static void main2(String[] args) {
/* 类抽象的：实例化
* 类实例化后，会返回一个自己的对象
* demo02 对象就是一个 Demo02类的具体的实例化
* 面向对象编程的本质就是：以类的方式组织代码，以对象的组织（封装）数据
* 类是对象的模板*/

    }


    public static void main1(String[] args) {
        Demo01 demo01 = new Demo01(); // 实例化，new 一个对象,可以实例化多个对象，
                                      // 但每一个对象是，相互独立的，互补干扰的
        System.out.println(demo01.name); // 亲疆
        Study16.change(demo01);
        System.out.println(demo01.name); // 秦疆
    }


    public static void change(Demo01 demo01) { // 对象作为形参
//        demo01 指向的——> demo01 = new Demo01(); 这是一个具体的对象，可以
//        通过该引用修改属性（字段）;
        demo01.name = "秦疆";
        System.out.println(demo01.name);

    }

}
